Skip to content

Add Invoke Taboo move and refactor Somniphobia to trigger on stamina gain#74

Merged
sudo-owen merged 3 commits into
mainfrom
claude/somniphobia-invoke-taboo-ow05m9
Jun 25, 2026
Merged

Add Invoke Taboo move and refactor Somniphobia to trigger on stamina gain#74
sudo-owen merged 3 commits into
mainfrom
claude/somniphobia-invoke-taboo-ow05m9

Conversation

@sudo-owen

Copy link
Copy Markdown
Collaborator

Summary

This PR introduces a new move Invoke Taboo for Xmon and refactors Somniphobia to detect stamina gains via the OnUpdateMonState hook rather than only triggering on rest actions. These changes improve the expressiveness of the effect system and enable more nuanced move mechanics.

Key Changes

Somniphobia Refactor

  • Changed trigger mechanism: Now activates on any stamina gain (resting, round-end regen, stamina-steal moves, etc.) via the OnUpdateMonState hook, rather than only on NO_OP (rest) actions
  • Changed scope: Moved from a single global effect to local per-mon effects on both active mons, allowing the effect to be cleared when a mon switches out
  • Updated step bitmap: Changed from RoundEnd | AfterMove to OnUpdateMonState | OnMonSwitchOut | RoundEnd with ALWAYS_APPLIES_BIT
  • Damage logic: Triggers only on stamina gains (valueToAdd > 0) to avoid recursion when the damage itself updates HP
  • Re-invocation: Calling Somniphobia while already active resets the duration rather than stacking

New Move: Invoke Taboo

  • Mechanic: A -1 priority move that reads the opponent's move after they act, brands it as taboo, and applies a local effect to the opponent's mon
  • Trigger: If the branded mon uses the tabooed move again before switching out, they fall asleep (via SleepStatus)
  • Scope: The brand is cleared when the branded mon switches out (OnMonSwitchOut hook returns true)
  • Implementation: Hybrid IMoveSet + BasicEffect that uses AfterMove to check for repeated moves and OnMonSwitchOut to clear the brand
  • Move validation: Only brands actual move slots (0–3); ignores switch and rest/no-op actions

Test Coverage

  • test_somniphobiaDamagesOnAnyStaminaGain: Validates that Somniphobia triggers on round-end stamina regen (non-rest gain) and does NOT trigger when a resting mon is already at full stamina (no gain)
  • test_invokeTabooSleepsOnRepeatedMove: Confirms that repeating a tabooed move applies sleep status
  • test_invokeTabooClearsOnSwitchOut: Verifies that the brand is cleared when the branded mon switches out

Deployment

  • Updated SetupMons.s.sol to deploy InvokeTaboo alongside other Xmon moves
  • Updated drool/moves.csv with Invoke Taboo move metadata

Notable Implementation Details

  • Somniphobia's OnUpdateMonState hook guards against recursion by only triggering on stamina gains; the damage it deals (an HP delta) re-enters the hook but is ignored because the state variable is HP, not Stamina
  • Invoke Taboo's move index packing stores the move slot directly in extraData and compares it against the packed move index from getMoveDecisionForBattleState, ensuring consistency across the branded move check and the trigger check
  • Both moves use ALWAYS_APPLIES_BIT in their step bitmap to ensure their hooks fire even when the effect is not the active move

https://claude.ai/code/session_01D3pJ3pS1brczwbbfRSYeoV

claude added 3 commits June 24, 2026 16:45
Somniphobia previously punished only the rest action by checking for a NO_OP
move in a global AfterMove hook. It now punishes *any* stamina gain (resting,
round-end stamina regen, stamina-steal moves, etc.) by listening at
OnUpdateMonState — the same hook Dreamcatcher uses to heal on stamina gain.
Because that hook only fires for local (per-mon) effects, Somniphobia is now
registered on both active mons rather than as a single global effect, and is
cleared on switch-out.

Invoke Taboo is a new Xmon move (-1 priority) that resolves after the opponent
acts, reads the move they just used, and brands it on their mon. Until they
switch out, repeating the branded move puts them to sleep. Wired into the
move catalog as Xmon's 5th (level-6) move and the deploy script.

Tests: rewrote the Somniphobia test for the new stamina-gain semantics
(round-end regen ticks; a full-stamina rest does nothing) and added Invoke
Taboo coverage (brand + sleep on repeat, and brand clears on switch-out).
Full suite: 487 passed, 0 failed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D3pJ3pS1brczwbbfRSYeoV
Per review feedback:
- Somniphobia is now a battlefield-wide effect again. A global coordinator
  holds the stack level and a 4-turn duration; it applies a per-mon copy to
  any mon that switches in (either side) and the copy clears on switch-out.
  The per-mon copies do the "damage on any stamina gain" via OnUpdateMonState
  (which only fires for per-mon effects). Damage scales with stack:
  1/8 max HP per stack. Re-casting raises the stack and refreshes duration.
- Duration cut from 8 to 4 turns.
- Removed the verbose comments from Somniphobia and the dev-note/prose
  comments from Invoke Taboo (moves.csv carries the descriptions).

Tests: added stacking, switch-in coverage, and expiry cases alongside the
any-stamina-gain test. Full suite: 490 passed, 0 failed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D3pJ3pS1brczwbbfRSYeoV
A re-cast now preserves the remaining duration instead of resetting it to
DURATION, so the effect must fade completely before it can be reset. Single
global instance is unchanged: both players casting accumulate into one
coordinator's stack.

Added test_somniphobiaRecastDoesNotRefreshDuration (expires on the original
4-round schedule despite a turn-2 re-cast) and test_somniphobiaSingleInstance
WhenBothCast (both sides casting -> one stack-2 coordinator).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D3pJ3pS1brczwbbfRSYeoV
@sudo-owen sudo-owen merged commit 02d4e35 into main Jun 25, 2026
1 check passed
@sudo-owen sudo-owen deleted the claude/somniphobia-invoke-taboo-ow05m9 branch June 25, 2026 17:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants